<template>
  <div class="page-wrapper-v3">
    <div class="page-container-v3">
    <el-card class="box-card-v3">
      <template #header>
        <div class="card-header-v3">
          <el-icon>
            <DataLine />
          </el-icon>
          <span style="margin-left: 10px;">数据初始化向导</span>
        </div>
      </template>

      <el-steps :active="activeStep" finish-status="success" align-center class="custom-steps">
        <el-step title="配置数据源">
          <template #icon>
            <Coin />
          </template>
        </el-step>
        <el-step title="初始化基金主体">
          <template #icon>
            <OfficeBuilding />
          </template>
        </el-step>
        <el-step title="初始化详细数据">
          <template #icon>
            <Finished />
          </template>
        </el-step>
      </el-steps>

      <transition name="fade" mode="out-in">
        <div :key="activeStep">
          <!-- Step 0: Configure Data Source -->
          <div v-if="activeStep === 0" class="step-content">
            <el-alert title="第一步：连接数据源" type="info"
              description="为继续初始化数据，请输入您的JoinQuant账户与密码用于数据访问验证。检测通过后的账号信息会安全保存在本地浏览器中，用于后续自动填充和快速校验。" :closable="false"
              show-icon class="step-alert"></el-alert>
            <div class="info-tip-card">
              <el-icon class="tip-icon">
                <InfoFilled />
              </el-icon>
              <div class="tip-content">
                <div class="tip-title">💡 提示</div>
                <ul class="tip-list">
                  <li>账号信息将加密保存在本地浏览器，仅用于数据访问验证</li>
                  <li>建议使用具有数据访问权限的正式账号，避免使用测试账号</li>
                  <li>如遇到连接问题，请检查网络连接或联系系统管理员</li>
                  <li>已填写默认账户，如果不自行配置会默认使用该账户配置数据源</li>
                </ul>
              </div>
            </div>
            <el-form :model="dataSourceForm" label-width="120px">
              <el-form-item label="聚源账户">
                <el-input v-model="dataSourceForm.username" placeholder="请输入您的聚源用户名" size="large"></el-input>
              </el-form-item>
              <el-form-item label="密码">
                <el-input type="password" v-model="dataSourceForm.password" placeholder="请输入您的聚源密码" size="large"
                  show-password></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="checkDataSourceAvailability" :loading="checkingAvailability"
                  size="large">
                  <el-icon>
                    <Connection />
                  </el-icon> <span style="margin-left: 8px;">检查可用性</span> </el-button>
                <el-link type="primary" href="https://www.joinquant.com/" target="_blank"
                  style="margin-left: 20px;">申请数据源账户</el-link>
              </el-form-item>
            </el-form>
            <div v-if="dataSourceStatus"
              :class="['status-display', dataSourceStatus.isAvailable ? 'status-success' : 'status-error']">
              <el-icon>
                <component :is="dataSourceStatus.isAvailable ? 'CircleCheckFilled' : 'CircleCloseFilled'" />
              </el-icon>
              <span style="margin-left: 8px;">{{ dataSourceStatus.message }}</span>
            </div>
          </div>

          <!-- Step 1: Initialize Universe -->
          <div v-if="activeStep === 1" class="step-content">
            <el-alert title="第二步：初始化基金主体" type="info" description="请定义您希望系统分析的基金范围，包括类型和初始化的样本数量。" :closable="false"
              show-icon class="step-alert"></el-alert>
            <div class="info-tip-card">
              <el-icon class="tip-icon">
                <InfoFilled />
              </el-icon>
              <div class="tip-content">
                <div class="tip-title">📊 说明</div>
                <ul class="tip-list">
                  <li><strong>样本数量：</strong>建议首次初始化选择 10-50 个样本，便于快速验证数据质量</li>
                  <li><strong>基金类型：</strong>XSHG/XSHE 为场内基金，OF 为场外基金，可根据分析需求选择</li>
                  <li><strong>注意事项：</strong>初始化过程可能需要几分钟，请耐心等待，不要关闭页面</li>
                </ul>
              </div>
            </div>
            <el-form :model="universeForm" label-width="120px">
              <el-form-item label="样本数量">
                <el-input-number v-model="universeForm.limit" :min="1" :max="1000" size="large"></el-input-number>
              </el-form-item>
              <el-form-item label="基金类型">
                <el-select v-model="universeForm.fund_types" multiple
                  placeholder="请选择一个或多个基金板块    : 如果选择基金板块为空则默认初始化OF类型" size="large" style="width: 100%;">
                  <el-option label="XSHG - 上海证券交易所(场内基金)" value="XSHG"></el-option>
                  <el-option label="XSHE - 深圳证券交易所(场内基金)" value="XSHE"></el-option>
                  <el-option label="OF - 开放式基金(场外基金)" value="OF"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item>
                <div class="universe-action-group">
                  <el-button type="primary" @click="startUniverseInitialization" :loading="isInitializingUniverse"
                    size="large"> <el-icon>
                      <CaretRight />
                    </el-icon> <span style="margin-left: 8px;">初始化基金主体</span> </el-button>
                  <div class="extract-tags-wrapper">
                    <el-checkbox v-model="extractTags" size="large" class="extract-tags-checkbox">
                      <span class="extract-tags-label">提取标签</span>
                    </el-checkbox>
                    <el-alert v-if="showExtractTagsWarning" type="warning" :closable="false" show-icon
                      class="extract-tags-warning">
                      <template #title>
                        <span class="warning-text">此选择十分必要，后续分析依赖此选择</span>
                      </template>
                    </el-alert>
                  </div>
                </div>
              </el-form-item>
            </el-form>
            <div v-if="showUniverseProgress || lastUniverseResult" class="step-progress-card">
              <div class="step-progress-header">
                <h4><el-icon>
                    <DataLine />
                  </el-icon><span>执行进度</span></h4>
                <p>实时反馈本次基金主体初始化的进展与结果。</p>
              </div>
              <div v-if="showUniverseProgress" class="progress-line">
                <el-progress :percentage="displayedUniverseProgress" :indeterminate="isUniverseIndeterminate"
                  :status="universeProgressStatus" :text-inside="true" :stroke-width="18" style="max-width: 520px;" />
              </div>
              <div v-if="lastUniverseResult" class="init-status-line">
                <el-tag :type="lastUniverseResult.status === 'success' ? 'success' : 'danger'">
                  {{ lastUniverseResult.status === 'success' ? '成功' : '失败' }}
                </el-tag>
                <span class="msg">{{ lastUniverseResult.message }}</span>
              </div>
              <!-- 提取标签进度 -->
              <div v-if="showTagExtractProgress || lastTagExtractResult" class="tag-extract-progress-wrapper">
                <div class="step-progress-header">
                  <h4><el-icon>
                      <DataLine />
                    </el-icon><span>提取标签进度</span></h4>
                  <p>正在为基金主体提取标签信息，此操作对后续分析至关重要。</p>
                </div>
                <div v-if="showTagExtractProgress" class="progress-line">
                  <el-progress :percentage="displayedTagExtractProgress" :indeterminate="isTagExtractIndeterminate"
                    :status="tagExtractProgressStatus" :text-inside="true" :stroke-width="18"
                    style="max-width: 520px;" />
                </div>
                <div v-if="lastTagExtractResult" class="init-status-line">
                  <el-tag :type="lastTagExtractResult.status === 'success' ? 'success' : 'danger'">
                    {{ lastTagExtractResult.status === 'success' ? '成功' : '失败' }}
                  </el-tag>
                  <span class="msg">{{ lastTagExtractResult.message }}</span>
                </div>
              </div>
            </div>
            <div class="table-container-step1">
              <el-table :data="universeData" v-if="universeData.length > 0" style="width: 100%; margin-top: 20px;"
                stripe>
                <el-table-column prop="code" label="基金代码" width="180"></el-table-column>
                <el-table-column prop="name" label="基金名称"></el-table-column>
                <el-table-column prop="type" label="基金类型" width="180"></el-table-column>
              </el-table>
            </div>
          </div>

          <!-- Step 2: Initialize Details -->
          <div v-if="activeStep === 2 || activeStep === 3" class="step-content-flex">
            <div class="step2-actions">
              <h4><el-icon>
                  <SetUp />
                </el-icon><span style="margin-left: 8px;">选择数据维度</span></h4>
              <p class="hint-text">持仓、公告初始化用时较长，建议分两次进行初始化，首次建议初始化（净值、融资融券、财务指标、每日收益）。</p>
              <div class="data-type-tips">
                <div class="tip-item">
                  <el-icon class="tip-icon-small">
                    <CircleCheck />
                  </el-icon>
                  <span><strong>基金净值：</strong>每日净值数据，用于收益分析和回测</span>
                </div>
                <div class="tip-item">
                  <el-icon class="tip-icon-small">
                    <CircleCheck />
                  </el-icon>
                  <span><strong>财务指标：</strong>不同季度财务数据，用于基本面分析</span>
                </div>
                <div class="tip-item">
                  <el-icon class="tip-icon-small">
                    <CircleCheck />
                  </el-icon>
                  <span><strong>融资融券：</strong>证券市场的信用交易数据</span>
                </div>
              </div>
              <el-checkbox-group v-model="selectedDataTypes">
                <el-checkbox label="FUND_MTSS">基金融资融券</el-checkbox>
                <el-checkbox label="FUND_ANNOUNCEMENT">基金公告</el-checkbox>
                <el-checkbox label="FUND_NET_VALUE">基金净值</el-checkbox>
                <el-checkbox label="FUND_PORTFOLIO_STOCK">基金持仓</el-checkbox>
                <el-checkbox label="FUND_FIN_INDICATOR">基金财务指标</el-checkbox>
                <el-checkbox label="FUND_MF_DAILY_PROFIT">货币基金每日收益</el-checkbox>
              </el-checkbox-group>
              <div class="action-buttons">
                <el-button type="primary" @click="startBatchInitialization" :loading="isBatchInitializing" size="large">
                  <el-icon>
                    <CaretRight />
                  </el-icon> <span style="margin-left: 8px;">采集基金数据</span> </el-button>
                <el-button v-if="step2Completed" type="success" @click="goHome" size="large"> <el-icon>
                    <HomeFilled />
                  </el-icon> <span style="margin-left: 8px;">回到首页</span> </el-button>
              </div>
            </div>
            <div class="step2-display">
              <div v-if="isBatchInitializing || Object.keys(previewData).length > 0 || step2Completed">
                <div v-if="showBatchProgress" class="progress-line" style="margin-bottom: 20px;">
                  <el-progress :percentage="displayedBatchProgress" :indeterminate="isBatchIndeterminate"
                    :status="batchProgressStatus" :text-inside="true" :stroke-width="18" style="max-width: 520px;" />
                </div>
                <div v-if="Object.keys(previewData).length > 0" style="width: 100%;">
                  <h4><el-icon>
                      <View />
                    </el-icon><span style="margin-left: 8px;">数据预览</span></h4>
                  <p class="hint-text">以下是最新加载数据的部分预览。</p>
                  <p class="scroll-hint">提示：表格列较多，可左右拖动滚动条查看全部字段。</p>
                  <div v-for="(items, type) in previewData" :key="type" style="margin-top: 10px; width: 100%;">
                    <h5>{{ type }}</h5>
                    <div class="table-container preview-table-wrapper">
                      <el-table :data="items.slice(0, 3)" class="preview-table" stripe border>
                        <el-table-column v-for="col in Object.keys(items[0] || {})" :key="col" :prop="col" :label="col"
                          min-width="120" />
                      </el-table>
                    </div>
                  </div>
                </div>
              </div>
              <el-empty v-else description="暂无预览数据，请在左侧选择并执行初始化"></el-empty>
            </div>
          </div>
        </div>
      </transition>

      <div class="navigation-buttons">
        <el-button @click="prevStep" v-if="activeStep > 0" size="large"> <el-icon>
            <ArrowLeft />
          </el-icon> <span>上一步</span> </el-button>
        <el-button @click="nextStep" :disabled="!isStepCompleted(activeStep)" v-if="activeStep < 2" size="large"
          type="primary"> <span>下一步</span> <el-icon>
            <ArrowRight />
          </el-icon> </el-button>
      </div>
    </el-card>
    </div>
    <!-- 问答机器人 -->
    <QABot />
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage, ElNotification } from 'element-plus';
import { DataLine, Coin, OfficeBuilding, Finished, Connection, CircleCheckFilled, CircleCloseFilled, CaretRight, SetUp, HomeFilled, View, ArrowLeft, ArrowRight, InfoFilled, CircleCheck } from '@element-plus/icons-vue';
import QABot from '@/components/QABot.vue';
import { initializeUniverse, batchInitializeData, initializeAnnouncements, initializeHoldings, checkDataSourceAvailability_, extractTagsForUniverse_ } from '@/api/dataInitializationApi';

const router = useRouter();

const DEFAULT_CREDENTIALS = Object.freeze({
  username: '19213200658',
  password: '00258741Lcy'
});
const CREDENTIALS_STORAGE_KEY = 'fund_init_credentials';

const checkingAvailability = ref(false);
const dataSourceForm = ref({ ...DEFAULT_CREDENTIALS });
const dataSourceStatus = ref(null);

const universeForm = ref({ limit: 10, fund_types: ['XSHG'] });
const isInitializingUniverse = ref(false);
const lastUniverseResult = ref(null);
const universeData = ref([]);
const extractTags = ref(false);
const isExtractingTags = ref(false);
const tagExtractProgress = ref(0);
const lastTagExtractResult = ref(null);
const showExtractTagsWarning = ref(false);

const selectedDataTypes = ref([]);
const isBatchInitializing = ref(false);
const lastBatchResult = ref(null);
const previewData = ref({});
const step2Completed = ref(false);

const activeStep = ref(0);

const STORAGE_KEY = "fund_init_wizard_v3";
const isBrowser = typeof window !== 'undefined';

function persistCredentials() {
  if (!isBrowser) return;
  window.localStorage.setItem(CREDENTIALS_STORAGE_KEY, JSON.stringify(dataSourceForm.value));
}

function loadStoredCredentials() {
  if (!isBrowser) return false;
  const stored = window.localStorage.getItem(CREDENTIALS_STORAGE_KEY);
  if (!stored) {
    dataSourceForm.value = { ...DEFAULT_CREDENTIALS };
    return false;
  }
  try {
    const parsed = JSON.parse(stored);
    if (parsed?.username && parsed?.password) {
      dataSourceForm.value = { username: parsed.username, password: parsed.password };
      return true;
    }
  } catch { }
  dataSourceForm.value = { ...DEFAULT_CREDENTIALS };
  return false;
}

function saveState() {
  sessionStorage.setItem(
    STORAGE_KEY,
    JSON.stringify({
      activeStep: activeStep.value,
      dataSourceStatus: dataSourceStatus.value,
      universeData: universeData.value,
      previewData: previewData.value,
      step2Completed: step2Completed.value,
      lastUniverseResult: lastUniverseResult.value,
      lastBatchResult: lastBatchResult.value,
      extractTags: extractTags.value,
      lastTagExtractResult: lastTagExtractResult.value,
    })
  );
}

function loadState() {
  const saved = sessionStorage.getItem(STORAGE_KEY);
  if (!saved) return;
  try {
    const obj = JSON.parse(saved);
    activeStep.value = obj.activeStep ?? 0;
    dataSourceStatus.value = obj.dataSourceStatus ?? null;
    universeData.value = obj.universeData ?? [];
    previewData.value = obj.previewData ?? {};
    step2Completed.value = obj.step2Completed ?? false;
    lastUniverseResult.value = obj.lastUniverseResult ?? null;
    lastBatchResult.value = obj.lastBatchResult ?? null;
    extractTags.value = obj.extractTags ?? false;
    lastTagExtractResult.value = obj.lastTagExtractResult ?? null;
  } catch { }
}

onMounted(() => {
  const credentialsLoaded = loadStoredCredentials();
  loadState();
  if (credentialsLoaded && !dataSourceStatus.value?.isAvailable) {
    checkDataSourceAvailability();
  }
});
onUnmounted(() => { sessionStorage.removeItem(STORAGE_KEY); });
watch([activeStep, dataSourceStatus, universeData, previewData, step2Completed, lastUniverseResult, lastBatchResult, extractTags, lastTagExtractResult], () => saveState(), { deep: true });

const showUniverseProgress = computed(() => isInitializingUniverse.value || !!lastUniverseResult.value);
const displayedUniverseProgress = computed(() => {
  const p = lastUniverseResult.value?.progress;
  if (isInitializingUniverse.value && (p == null || p === 0)) return 30;
  return p || 0;
});
const isUniverseIndeterminate = computed(() => isInitializingUniverse.value && (!lastUniverseResult.value || !lastUniverseResult.value.progress));

const showBatchProgress = computed(() => isBatchInitializing.value || !!lastBatchResult.value);
const displayedBatchProgress = computed(() => {
  const p = lastBatchResult.value?.progress;
  if (isBatchInitializing.value && (p == null || p === 0)) return 30;
  return p || 0;
});
const isBatchIndeterminate = computed(() => isBatchInitializing.value && (!lastBatchResult.value || !lastBatchResult.value.progress));

function mapProgressStatus(status) {
  if (status === 'success') return 'success';
  if (status === 'fail' || status === 'error') return 'exception';
  return undefined;
}

const universeProgressStatus = computed(() => (isInitializingUniverse.value ? undefined : mapProgressStatus(lastUniverseResult.value?.status)));
const batchProgressStatus = computed(() => (isBatchInitializing.value ? undefined : mapProgressStatus(lastBatchResult.value?.status)));

const showTagExtractProgress = computed(() => isExtractingTags.value || !!lastTagExtractResult.value);
const displayedTagExtractProgress = computed(() => {
  const p = lastTagExtractResult.value?.progress;
  if (isExtractingTags.value && (p == null || p === 0)) return 30;
  return p || 0;
});
const isTagExtractIndeterminate = computed(() => isExtractingTags.value && (!lastTagExtractResult.value || !lastTagExtractResult.value.progress));
const tagExtractProgressStatus = computed(() => {
  if (isExtractingTags.value) return undefined;
  const status = lastTagExtractResult.value?.status;
  // 确保 status 是字符串类型进行比较
  if (typeof status === 'string' && status === 'success') {
    return 'success';
  }
  if (typeof status === 'string' && (status === 'fail' || status === 'error')) {
    return 'exception';
  }
  return undefined;
});

function normalizeResultPayload(raw, fallbackMessage = '', fallbackStatus = 'success') {
  const data = raw || {};
  return {
    ...data,
    message: data.message || fallbackMessage,
    status: data.status || fallbackStatus,
    progress: data.progress ?? 100,
  };
}

const checkDataSourceAvailability = async () => {
  if (!dataSourceForm.value.username || !dataSourceForm.value.password) {
    ElMessage.warning("请输入账户和密码");
    return;
  }
  checkingAvailability.value = true;
  try {
    const resp = await checkDataSourceAvailability_({ account: dataSourceForm.value.username, password: dataSourceForm.value.password });
    if (resp.data.status === "success") {
      dataSourceStatus.value = { isAvailable: true, message: '数据源配置成功' };
      ElMessage.success(`账户可用`);
      persistCredentials();
    } else {
      dataSourceStatus.value = { isAvailable: false, message: resp.data.message };
      ElMessage.error(resp.data.message);
    }
  } catch {
    dataSourceStatus.value = { isAvailable: false, message: "检查失败" };
    ElMessage.error("检查失败");
  } finally {
    checkingAvailability.value = false;
  }
};

const startUniverseInitialization = async () => {
  if (!dataSourceStatus.value?.isAvailable) {
    ElMessage.warning("请先检查数据源可用性");
    return;
  }
  if (!extractTags.value) {
    showExtractTagsWarning.value = true;
    setTimeout(() => {
      showExtractTagsWarning.value = false;
    }, 5000);
    return;
  }
  showExtractTagsWarning.value = false;
  isInitializingUniverse.value = true;
  lastUniverseResult.value = null;
  lastTagExtractResult.value = null;
  universeData.value = [];
  try {
    const resp = await initializeUniverse({ ...dataSourceForm.value, ...universeForm.value });
    universeData.value = resp.data.preview || [];
    lastUniverseResult.value = normalizeResultPayload(resp?.data, resp?.data?.message || '基金主体初始化完成');
    ElMessage.success(resp.data.message);

    // 如果选择了提取标签，执行提取标签操作
    if (extractTags.value) {
      await extractTagsForUniverse();
    }
  } catch {
    lastUniverseResult.value = { status: 'fail', message: '基金主体初始化失败', progress: 0 };
    ElMessage.error("基金主体初始化失败");
  } finally {
    isInitializingUniverse.value = false;
  }
};

const extractTagsForUniverse = async () => {
  isExtractingTags.value = true;
  tagExtractProgress.value = 0;
  lastTagExtractResult.value = null;
  try {
    const resp = await extractTagsForUniverse_();
    const responseData = resp?.data || {};

    // 获取 state 字段（可能在顶层，也可能在嵌套结构中）
    const state = responseData.state || responseData.status;
    // 获取实际数据（可能在 data 字段中，也可能直接在顶层）
    const data = responseData.data || responseData;

    // 根据 state 字段判断成功/失败
    if (state === 'success') {
      const message = `标签提取成功：处理 ${data.processedFunds || 0} 个基金，新增 ${data.newTags || 0} 个标签，新增 ${data.newRelations || 0} 个关系`;

      // 使用 Vue.nextTick 确保响应式更新
      lastTagExtractResult.value = {
        processedFunds: data.processedFunds,
        newTags: data.newTags,
        newRelations: data.newRelations,
        executedAt: data.executedAt,
        status: 'success', // 必须明确设置为 'success'
        message: message,
        progress: 100
      };
      tagExtractProgress.value = 100;
      ElMessage.success(message);
    } else {
      // state 不是 success 或不存在，视为失败
      lastTagExtractResult.value = {
        status: 'fail',
        message: responseData.message || `标签提取失败（state: ${state || 'undefined'}）`,
        progress: 0
      };
      tagExtractProgress.value = 0;
      ElMessage.error(responseData.message || '标签提取失败');
    }
  } catch (error) {
    lastTagExtractResult.value = {
      status: 'fail',
      message: error?.response?.data?.message || error?.response?.data?.data?.message || '标签提取失败',
      progress: 0
    };
    tagExtractProgress.value = 0;
    ElMessage.error(error?.response?.data?.message || error?.response?.data?.data?.message || '标签提取失败');
  } finally {
    isExtractingTags.value = false;
  }
};

const startBatchInitialization = async () => {
  if (selectedDataTypes.value.length === 0) {
    ElMessage.warning("请选择数据类型");
    return;
  }
  if (!dataSourceStatus.value?.isAvailable) {
    ElMessage.warning("请先检查数据源可用性");
    return;
  }
  previewData.value = {};
  isBatchInitializing.value = true;
  lastBatchResult.value = null;
  const special = ['FUND_ANNOUNCEMENT', 'FUND_PORTFOLIO_STOCK'];
  const normal = selectedDataTypes.value.filter(t => !special.includes(t));
  try {
    for (const type of selectedDataTypes.value) {
      if (type === 'FUND_ANNOUNCEMENT') {
        await initializeAnnouncements();
      } else if (type === 'FUND_PORTFOLIO_STOCK') {
        await initializeHoldings();
      }
    }
    if (normal.length > 0) {
      const resp = await batchInitializeData({ ...dataSourceForm.value, dataTypes: normal, mode: "AUTO_UPDATE", strategy: "INCREMENTAL" });
      if (resp.data.preview && Object.keys(resp.data.preview).length > 0) {
        previewData.value = { ...previewData.value, ...resp.data.preview };
      } else {
        ElMessage.info("无增量数据");
      }
      lastBatchResult.value = normalizeResultPayload(resp?.data, resp?.data?.message || '基金数据采集完成');
    } else {
      lastBatchResult.value = { status: 'success', message: '专项数据采集完成', progress: 100 };
    }
    step2Completed.value = true;
    activeStep.value = 3;
    ElNotification({ title: '初始化完成', message: '您的数据已准备就绪。', type: 'success', duration: 3000 });
  } catch {
    lastBatchResult.value = { status: 'fail', message: '初始化失败', progress: 0 };
    ElMessage.error("初始化失败");
  } finally {
    isBatchInitializing.value = false;
  }
};

const isStepCompleted = (step) => {
  if (step === 0) return dataSourceStatus.value?.isAvailable;
  if (step === 1) {
    // 必须完成基金主体初始化
    if (universeData.value.length === 0) return false;
    // 如果选择了提取标签，必须完成标签提取且成功
    if (extractTags.value) {
      return lastTagExtractResult.value?.status === 'success';
    }
    // 如果没有选择提取标签，只需要完成基金主体初始化
    return true;
  }
  return false;
};

const prevStep = () => { if (activeStep.value > 0) activeStep.value--; };
const nextStep = () => { if (activeStep.value < 2) activeStep.value++; };
const goHome = () => { router.push("/funds"); };

</script>

<style scoped>
.page-wrapper-v3 {
  width: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  height: 100vh;
}

.page-container-v3 {
  padding: 40px;
  min-height: 100vh;
  background: linear-gradient(135deg, #e3f2fd 0%, #f0f9ff 25%, #ffffff 60%, #fafcff 100%);
  position: relative;
  overflow-x: hidden;
  transform: scale(0.85);
  transform-origin: top center;
  width: 117.65%; /* 100% / 0.85 以保持原始宽度 */
  margin-left: -8.825%; /* 居中调整 */
  margin-bottom: calc(-15vh * 0.85); /* 补偿缩放后的高度，减少底部空白 */
  padding-bottom: calc(40px / 0.85); /* 调整底部内边距 */
}

.page-container-v3::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background:
    radial-gradient(circle at 20% 30%, rgba(64, 158, 255, 0.08) 0%, transparent 50%),
    radial-gradient(circle at 80% 70%, rgba(102, 126, 234, 0.06) 0%, transparent 50%);
  pointer-events: none;
  z-index: 0;
}

.box-card-v3 {
  width: 80%;
  max-width: 1200px;
  margin: 0 auto;
  border: none;
  border-radius: 20px;
  background: linear-gradient(to bottom, #ffffff 0%, #f9fcff 100%);
  box-shadow:
    0 20px 60px rgba(64, 158, 255, 0.15),
    0 8px 24px rgba(0, 0, 0, 0.08),
    0 0 0 1px rgba(64, 158, 255, 0.1);
  overflow: hidden;
  position: relative;
  z-index: 1;
  transition: all 0.3s ease;
}

.box-card-v3:hover {
  box-shadow:
    0 24px 72px rgba(64, 158, 255, 0.18),
    0 12px 32px rgba(0, 0, 0, 0.1),
    0 0 0 1px rgba(64, 158, 255, 0.15);
  transform: translateY(-2px);
}

.card-header-v3 {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  font-weight: 700;
  color: #303133;
  padding: 28px 0;
  background: linear-gradient(135deg, rgba(168, 198, 237, 0.63) 0%, rgba(168, 237, 234, 0.63) 50%, rgba(255, 255, 255, 0.95) 100%);
  border-bottom: 2px solid rgba(64, 158, 255, 0.15);
  position: relative;
  overflow: hidden;
}

.card-header-v3::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  animation: shimmer 3s infinite;
}

@keyframes shimmer {
  0% {
    left: -100%;
  }

  100% {
    left: 100%;
  }
}

.custom-steps {
  padding: 20px;
}

.step-content,
.step-content-flex {
  margin-top: 20px;
  padding: 20px 40px;
}

.step-content {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.step-content-flex {
  display: flex;
  gap: 40px;
}

.step-alert {
  width: 100%;
  margin-bottom: 24px;
  background: linear-gradient(135deg, #f0f9ff 0%, #e8f4ff 100%);
  border: 1px solid rgba(64, 158, 255, 0.2);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.08);
}

.info-tip-card {
  width: 100%;
  max-width: 700px;
  margin: 20px 0 30px;
  padding: 20px 24px;
  background: linear-gradient(135deg, #f8fbff 0%, #ffffff 100%);
  border: 1px solid rgba(64, 158, 255, 0.15);
  border-left: 4px solid #409EFF;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
  display: flex;
  gap: 16px;
  transition: all 0.3s ease;
}

.info-tip-card:hover {
  box-shadow: 0 6px 16px rgba(64, 158, 255, 0.15);
  transform: translateX(4px);
}

.tip-icon {
  font-size: 24px;
  color: #409EFF;
  flex-shrink: 0;
  margin-top: 2px;
}

.tip-content {
  flex: 1;
}

.tip-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 12px;
}

.tip-list {
  margin: 0;
  padding-left: 20px;
  list-style: none;
}

.tip-list li {
  font-size: 14px;
  color: #606266;
  line-height: 1.8;
  margin-bottom: 8px;
  position: relative;
  padding-left: 12px;
}

.tip-list li::before {
  content: '•';
  position: absolute;
  left: 0;
  color: #409EFF;
  font-weight: bold;
}

.tip-list li:last-child {
  margin-bottom: 0;
}

.data-type-tips {
  margin: 16px 0 24px;
  padding: 16px 20px;
  background: linear-gradient(135deg, #f5f9ff 0%, #ffffff 100%);
  border: 1px solid rgba(64, 158, 255, 0.12);
  border-radius: 10px;
}

.tip-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 13px;
  color: #606266;
  line-height: 1.6;
}

.tip-item:last-child {
  margin-bottom: 0;
}

.tip-icon-small {
  font-size: 16px;
  color: #67c23a;
  margin-top: 2px;
  flex-shrink: 0;
}

.step2-actions {
  flex: 1;
  padding-right: 40px;
  border-right: 1px solid #eef2f7;
}

.step2-actions h4,
.step2-display h4 {
  display: flex;
  align-items: center;
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 8px;
  color: #333;
}

.hint-text {
  font-size: 14px;
  color: #5a697e;
  margin-bottom: 25px;
  line-height: 1.6;
}

.step2-actions .el-checkbox-group {
  display: flex;
  flex-direction: column;
}

.step2-actions .el-checkbox {
  margin-bottom: 18px;
}

.action-buttons {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.universe-action-group {
  display: flex;
  align-items: center;
  gap: 30px;
  flex-wrap: wrap;
  width: 100%;
}

.extract-tags-wrapper {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex-shrink: 0;
}

.extract-tags-checkbox {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  padding: 0;
  height: 40px;
  line-height: 40px;
  display: inline-flex;
  align-items: center;
  padding-left: 16px;
  padding-right: 16px;
  background: linear-gradient(135deg, #f8fbff 0%, #ffffff 100%);
  border: 2px solid rgba(64, 158, 255, 0.3);
  border-radius: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.extract-tags-checkbox:hover {
  border-color: rgba(64, 158, 255, 0.5);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
  transform: translateY(-2px);
}

.extract-tags-checkbox.is-checked {
  background: linear-gradient(135deg, #e3f2fd 0%, #f0f9ff 100%);
  border-color: #409EFF;
  box-shadow: 0 4px 16px rgba(64, 158, 255, 0.2);
}

.extract-tags-checkbox :deep(.el-checkbox__input) {
  margin-right: 12px;
}

.extract-tags-checkbox :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #409EFF;
  border-color: #409EFF;
  width: 18px;
  height: 18px;
}

.extract-tags-checkbox :deep(.el-checkbox__input .el-checkbox__inner) {
  width: 18px;
  height: 18px;
  border: 2px solid rgba(64, 158, 255, 0.5);
}

.extract-tags-label {
  margin-left: 8px;
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  letter-spacing: 0.3px;
}

.extract-tags-warning {
  margin-top: 0;
  border-radius: 10px;
  border: 1px solid rgba(230, 162, 60, 0.3);
  background: linear-gradient(135deg, #fef9e7 0%, #fff8e1 100%);
  box-shadow: 0 2px 8px rgba(230, 162, 60, 0.15);
  animation: slideIn 0.3s ease;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.extract-tags-warning :deep(.el-alert__content) {
  padding: 0;
}

.warning-text {
  font-size: 14px;
  font-weight: 500;
  color: #e6a23c;
}

.tag-extract-progress-wrapper {
  margin-top: 40px;
  padding-top: 30px;
  border-top: 2px dashed rgba(64, 158, 255, 0.2);
}

.step2-display {
  flex: 2.6;
  min-width: 0;
  padding-left: 30px;
}

.el-form {
  width: 700px;
  padding: 24px;
  background: linear-gradient(135deg, #fafcff 0%, #ffffff 100%);
  border-radius: 16px;
  border: 1px solid rgba(64, 158, 255, 0.1);
  box-shadow: 0 4px 16px rgba(64, 158, 255, 0.08);
}

.el-form :deep(.el-form-item__label) {
  font-weight: 600;
  color: #303133;
}

.el-form :deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px rgba(64, 158, 255, 0.2) inset;
  transition: all 0.3s ease;
}

.el-form :deep(.el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px rgba(64, 158, 255, 0.4) inset;
}

.el-form :deep(.el-button--primary) {
  background: linear-gradient(135deg, #409EFF 0%, #66b1ff 100%);
  border: none;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
  transition: all 0.3s ease;
}

.el-form :deep(.el-button--primary:hover) {
  box-shadow: 0 6px 16px rgba(64, 158, 255, 0.4);
  transform: translateY(-2px);
}

.status-display {
  margin-top: 20px;
  padding: 16px 24px;
  border-radius: 12px;
  font-weight: 500;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  transition: all 0.3s ease;
}

.status-success {
  color: #67c23a;
  background: linear-gradient(135deg, #f0f9eb 0%, #e8f5e8 100%);
  border: 1px solid rgba(103, 194, 58, 0.3);
}

.status-error {
  color: #f56c6c;
  background: linear-gradient(135deg, #fef0f0 0%, #fde2e2 100%);
  border: 1px solid rgba(245, 108, 108, 0.3);
}

.step-progress-card {
  width: 100%;
  max-width: 700px;
  margin-top: 24px;
  padding: 24px 28px;
  border-radius: 16px;
  border: 1px solid rgba(64, 158, 255, 0.2);
  background: linear-gradient(135deg, #f6fbff 0%, #ffffff 100%);
  box-shadow:
    0 4px 16px rgba(64, 158, 255, 0.12),
    0 2px 8px rgba(0, 0, 0, 0.06);
  transition: all 0.3s ease;
}

.step-progress-card:hover {
  box-shadow:
    0 6px 20px rgba(64, 158, 255, 0.15),
    0 4px 12px rgba(0, 0, 0, 0.08);
}

.step-progress-header {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
}

.step-progress-header h4 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.step-progress-header p {
  margin: 0;
  color: #5a697e;
  font-size: 13px;
}

.init-status-line {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 0 0;
  padding: 14px 18px;
  border-radius: 10px;
  background: linear-gradient(135deg, #f5f9ff 0%, #ffffff 100%);
  border-left: 4px solid rgba(64, 158, 255, 0.4);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.init-status-line .msg {
  color: #606266;
  font-size: 14px;
  font-weight: 500;
  flex: 1;
}

.navigation-buttons {
  margin-top: 40px;
  padding: 20px;
  text-align: center;
  border-top: 1px solid #f0f2f5;
}

.table-container,
.table-container-step1 {
  overflow-x: auto;
  width: 100%;
}

.table-container-step1 {
  max-width: 700px;
}

.progress-line {
  margin: 20px 0;
  padding: 20px 24px;
  background: linear-gradient(135deg, #f5f9ff 0%, #ffffff 100%);
  border-radius: 12px;
  border: 1px solid rgba(64, 158, 255, 0.1);
  box-shadow:
    0 4px 12px rgba(64, 158, 255, 0.1),
    0 2px 6px rgba(0, 0, 0, 0.04);
}

.preview-table-wrapper {
  max-width: 100%;
  width: 100%;
  overflow-x: auto;
  padding-bottom: 12px;
  margin-top: 10px;
  border-radius: 10px;
  border: 1px solid rgba(82, 125, 227, 0.15);
  background: linear-gradient(135deg, rgba(245, 247, 255, 0.8), rgba(255, 255, 255, 0.9));
}

.preview-table {
  width: max-content;
  min-width: 700px;
}

@supports not (width: max-content) {
  .preview-table {
    width: 100%;
  }
}

.preview-table-wrapper {
  scrollbar-color: #7a8cff rgba(224, 230, 247, 0.9);
  scrollbar-width: thin;
}

.preview-table-wrapper::-webkit-scrollbar {
  height: 10px;
}

.preview-table-wrapper::-webkit-scrollbar-track {
  background: rgba(224, 230, 247, 0.9);
  border-radius: 999px;
}

.preview-table-wrapper::-webkit-scrollbar-thumb {
  background: linear-gradient(90deg, #7a8cff, #5e6bff);
  border-radius: 999px;
}

.scroll-hint {
  font-size: 13px;
  color: #6c7a92;
  margin-top: -12px;
}

.el-button .el-icon {
  font-size: 16px;
}

.el-button span+.el-icon,
.el-icon+span {
  margin-left: 8px;
}

/* Transition Animation */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.4s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
